summaryrefslogtreecommitdiffstats
path: root/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
blob: b225e10fbf01f802f2fc5741489f8d435891b765 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <array>
#include <memory>
#include <thread>

#include "audio_core/adsp/apps/audio_renderer/command_buffer.h"
#include "audio_core/adsp/apps/audio_renderer/command_list_processor.h"
#include "audio_core/adsp/mailbox.h"
#include "common/common_types.h"
#include "common/polyfill_thread.h"
#include "common/reader_writer_queue.h"
#include "common/thread.h"

namespace Core {
class System;
namespace Timing {
struct EventType;
}
namespace Memory {
class Memory;
}
class System;
} // namespace Core

namespace AudioCore {
namespace Sink {
class Sink;
}

namespace ADSP::AudioRenderer {

enum Message : u32 {
    Invalid = 0x00,
    MapUnmap_Map = 0x01,
    MapUnmap_MapResponse = 0x02,
    MapUnmap_Unmap = 0x03,
    MapUnmap_UnmapResponse = 0x04,
    MapUnmap_InvalidateCache = 0x05,
    MapUnmap_InvalidateCacheResponse = 0x06,
    MapUnmap_Shutdown = 0x07,
    MapUnmap_ShutdownResponse = 0x08,
    InitializeOK = 0x16,
    RenderResponse = 0x20,
    Render = 0x2A,
    Shutdown = 0x34,
};

/**
 * The AudioRenderer application running on the ADSP.
 */
class AudioRenderer {
public:
    explicit AudioRenderer(Core::System& system, Core::Memory::Memory& memory, Sink::Sink& sink);
    ~AudioRenderer();

    /**
     * Start the AudioRenderer.
     *
     * @param mailbox The mailbox to use for this session.
     */
    void Start();

    /**
     * Stop the AudioRenderer.
     */
    void Stop();

    void Signal();
    void Wait();

    void Send(Direction dir, MailboxMessage message);
    MailboxMessage Receive(Direction dir, bool block = true);

    void SetCommandBuffer(s32 session_id, CommandBuffer& buffer) noexcept;
    u32 GetRemainCommandCount(s32 session_id) const noexcept;
    void ClearRemainCommandCount(s32 session_id) noexcept;
    u64 GetRenderingStartTick(s32 session_id) const noexcept;

private:
    /**
     * Main AudioRenderer thread, responsible for processing the command lists.
     */
    void Main(std::stop_token stop_token);

    /**
     * Creates the streams which will receive the processed samples.
     */
    void CreateSinkStreams();

    /// Core system
    Core::System& system;
    /// Memory
    Core::Memory::Memory& memory;
    /// The output sink the AudioRenderer will use
    Sink::Sink& sink;
    /// The active mailbox
    Mailbox mailbox;
    /// Main thread
    std::jthread main_thread{};
    /// The current state
    std::atomic<bool> running{};
    std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
    /// The command lists to process
    std::array<CommandListProcessor, MaxRendererSessions> command_list_processors{};
    /// The streams which will receive the processed samples
    std::array<Sink::SinkStream*, MaxRendererSessions> streams{};
    u64 signalled_tick{0};
};

} // namespace ADSP::AudioRenderer
} // namespace AudioCore